from fastapi import FastAPI, Header, HTTPException, Depends
from typing import Union

# app = FastAPI()


async def verify_token(x_token: str = Header()):
    if x_token != "fake-super-secret-token":
        raise HTTPException(status_code=400, detail="X-Token header invalid")


async def verify_key(x_key: str = Header()):
    if x_key != "fake-super-secret-key":
        raise HTTPException(status_code=400, detail="X-Key header invalid")
    return x_key


# 全局依赖
# 添加全局依赖后，所有的接口都需要携带对应的 Header 信息
app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])

# 1. 依赖项的使用步骤
# 1.1 导入 Depends
# from fastapi import Depends


# 1.2 定义一个通用的依赖项
async def common_parameters(
    q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
    return {"q": q, "skip": skip, "limit": limit}


# 1.3 通过 Depends(common_parameters) 使用依赖项
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
    return commons


@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
    return commons


# 2. 使用类作为依赖项
fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


class CommonQueryParams:
    def __init__(self, q: str | None = None, skip: int = 0, limit: int = 100):
        self.q = q
        self.skip = skip
        self.limit = limit


@app.get("/items2/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
    response = {}
    if commons.q:
        response.update({"q": commons.q})
    items = fake_items_db[commons.skip : commons.skip + commons.limit]
    response.update({"items": items})
    return response


# 3. 子依赖项
def get_query_params(q: str | None = None):
    return q


def get_filtered_items(query: str = Depends(get_query_params)):
    return [item for item in fake_items_db if query in item["item_name"]]


@app.get("/items3")
def read_items(filtered: list = Depends(get_filtered_items)):
    return filtered


# 4. 在路径操作装饰器中使用依赖项
# 路径操作装饰器支持可选参数 ~ dependencies。
# 该参数的值是由 Depends() 组成的 list


@app.get("/items4/", dependencies=[Depends(verify_token), Depends(verify_key)])
async def read_items():
    return [{"item": "Foo"}, {"item": "Bar"}]


# 5. 全局依赖


@app.get("/items5/")
async def read_items():
    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]


@app.get("/users/")
async def read_users():
    return [{"username": "Rick"}, {"username": "Morty"}]
